package com.wisdom.smartbook.app;

import android.content.Context;
import android.content.Intent;

import androidx.multidex.MultiDexApplication;

import com.tencent.smtt.export.external.TbsCoreSettings;
import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.TbsDownloader;
import com.tencent.smtt.sdk.TbsListener;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.utils.LogFileUtils;
import com.wisdom.smartbook.listener.CameraPreviewListener;
import com.wisdom.smartbook.receiver.X5ProcessInitService;
import com.wisdom.smartbook.utils.CrashHandler;
import com.wisdom.smartbook.utils.KLog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 主程序入口
 */

public class MyApp extends MultiDexApplication {
    private static MyApp mInstance;
    //版本类型 1 生产，2 测试，3 本地
    public static int BUILD_TYPE = 2;
    protected static Context mAppContext;
    private boolean isX5Finish = false;
    private List<CameraPreviewListener> mPreviewListenerList;
    private boolean isLoginSuccess = false;

    @Override
    public void onCreate() {
        super.onCreate();

        mAppContext = this;
        mInstance = this;
        initX5Tbs();
//        initTencentTbs();
        //初始化异常捕获
        CrashHandler.getInstance().initCrashHandler(MyApp.getInstance());


    }


    public static Context getAppContext() {
        return mAppContext;
    }

    public static MyApp getInstance() {
        return mInstance;
    }

    public boolean isX5Finish() {
        return isX5Finish;
    }


    public void initX5Tbs() {
        QbSdk.initX5Environment(mAppContext, new QbSdk.PreInitCallback() {
            @Override
            public void onCoreInitFinished() {
                // 内核初始化完成，可能为系统内核，也可能为系统内核
                KLog.d("x5加载完成");
            }

            /**
             * 预初始化结束
             * 由于X5内核体积较大，需要依赖网络动态下发，所以当内核不存在的时候，默认会回调false，此时将会使用系统内核代替
             * @param isX5 是否使用X5内核
             */
            @Override
            public void onViewInitFinished(boolean isX5) {
                KLog.d("是否支持x5", isX5);
                isX5Finish = true;

            }
        });

        // 在调用TBS初始化、创建WebView之前进行如下配置
//        HashMap map = new HashMap();
//        map.put(TbsCoreSettings.TBS_SETTINGS_USE_SPEEDY_CLASSLOADER, true);
//        map.put(TbsCoreSettings.TBS_SETTINGS_USE_DEXLOADER_SERVICE, true);
//        QbSdk.initTbsSettings(map);
        QbSdk.setDownloadWithoutWifi(true);

        QbSdk.setTbsListener(new TbsListener() {
            @Override
            public void onDownloadFinish(int i) {
            }
            @Override
            public void onInstallFinish(int i) {
                KLog.e("onInstallFinish: 内核下载成功" );
            }
            @Override
            public void onDownloadProgress(int progress) {
                KLog.i( "Core Downloading: " + progress);

            }
        });
        boolean needDownload = TbsDownloader.needDownload(this, TbsDownloader.DOWNLOAD_OVERSEA_TBS);
        KLog.e("onCreate: "+needDownload );
        if (needDownload) {
            TbsDownloader.startDownload(this);
        }
    }

    public void initTencentTbs() {

        /* [new] 独立Web进程演示  */
        if (!startX5WebProcessPreinitService()) {
            return;
        }

        // 在调用TBS初始化、创建WebView之前进行如下配置
//        HashMap map = new HashMap();
//        map.put(TbsCoreSettings.TBS_SETTINGS_USE_SPEEDY_CLASSLOADER, true);
//        map.put(TbsCoreSettings.TBS_SETTINGS_USE_DEXLOADER_SERVICE, true);
//        QbSdk.initTbsSettings(map);

        /* 设置允许移动网络下进行内核下载。默认不下载，会导致部分一直用移动网络的用户无法使用x5内核 */
        QbSdk.setDownloadWithoutWifi(true);

        QbSdk.setCoreMinVersion(QbSdk.CORE_VER_ENABLE_202112);
        /* SDK内核初始化周期回调，包括 下载、安装、加载 */

        QbSdk.setTbsListener(new TbsListener() {

            /**
             * @param stateCode 用户可处理错误码请参考{@link com.tencent.smtt.sdk.TbsCommonCode}
             */
            @Override
            public void onDownloadFinish(int stateCode) {
                KLog.i( "onDownloadFinished: " + stateCode);
            }

            /**
             * @param stateCode 用户可处理错误码请参考{@link com.tencent.smtt.sdk.TbsCommonCode}
             */
            @Override
            public void onInstallFinish(int stateCode) {
                KLog.i( "onInstallFinished: " + stateCode);
            }

            /**
             * 首次安装应用，会触发内核下载，此时会有内核下载的进度回调。
             * @param progress 0 - 100
             */
            @Override
            public void onDownloadProgress(int progress) {
                KLog.i( "Core Downloading: " + progress);
            }
        });

        /* 此过程包括X5内核的下载、预初始化，接入方不需要接管处理x5的初始化流程，希望无感接入 */
        QbSdk.initX5Environment(this, new QbSdk.PreInitCallback() {
            @Override
            public void onCoreInitFinished() {
                // 内核初始化完成，可能为系统内核，也可能为系统内核
            }

            /**
             * 预初始化结束
             * 由于X5内核体积较大，需要依赖wifi网络下发，所以当内核不存在的时候，默认会回调false，此时将会使用系统内核代替
             * 内核下发请求发起有24小时间隔，卸载重装、调整系统时间24小时后都可重置
             * 调试阶段建议通过 WebView 访问 debugtbs.qq.com -> 安装线上内核 解决
             * @param isX5 是否使用X5内核
             */
            @Override
            public void onViewInitFinished(boolean isX5) {
                KLog.i( "onViewInitFinished: " + isX5);
                // hint: you can use QbSdk.getX5CoreLoadHelp(context) anytime to get help.
            }
        });

        boolean needDownload = TbsDownloader.needDownload(this, TbsDownloader.DOWNLOAD_OVERSEA_TBS);
        KLog.e("onCreate: "+needDownload );
        if (needDownload) {
            TbsDownloader.startDownload(this);
        }
    }

    /**
     * 启动X5 独立Web进程的预加载服务。优点：
     * 1、后台启动，用户无感进程切换
     * 2、启动进程服务后，有X5内核时，X5预加载内核
     * 3、Web进程Crash时，不会使得整个应用进程crash掉
     * 4、隔离主进程的内存，降低网页导致的App OOM概率。
     *
     * 缺点：
     * 进程的创建占用手机整体的内存，demo 约为 150 MB
     */
    private boolean startX5WebProcessPreinitService() {
        String currentProcessName = QbSdk.getCurrentProcessName(this);
        // 设置多进程数据目录隔离，不设置的话系统内核多个进程使用WebView会crash，X5下可能ANR
        WebView.setDataDirectorySuffix(QbSdk.getCurrentProcessName(this));
        KLog.i( currentProcessName);
        if (currentProcessName.equals(this.getPackageName())) {
            this.startService(new Intent(this, X5ProcessInitService.class));
            return true;
        }
        return false;
    }


    public void addPreviewListener(CameraPreviewListener listener) {
        if (mPreviewListenerList == null) {
            mPreviewListenerList = new ArrayList<>();
        }
        mPreviewListenerList.add(listener);
    }

    public void removePreviewListener() {
        if (mPreviewListenerList != null) {
            mPreviewListenerList.clear();
        }
    }

    public List<CameraPreviewListener> getPreviewListenerList() {
        if (mPreviewListenerList == null) {
            mPreviewListenerList = new ArrayList<>();
        }
        return mPreviewListenerList;
    }

    public void setIsLoginSuccess(boolean isLogin) {
        isLoginSuccess = isLogin;
    }

    public boolean isLoginSuccess() {
        return isLoginSuccess;
    }
}
